package com.brzjomo.secretiveworld.object.block;

import java.util.List;

import javax.annotation.Nullable;

import com.brzjomo.secretiveworld.init.ModBlocks;
import com.brzjomo.secretiveworld.init.ModTileEntityTypes;
import com.brzjomo.secretiveworld.inventory.container.GreedyChestContainer;
import com.brzjomo.secretiveworld.tileentity.GreedyChestTileEntity;

import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.HorizontalBlock;
import net.minecraft.block.material.PushReaction;
import net.minecraft.client.util.ITooltipFlag;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.item.ItemEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.ServerPlayerEntity;
import net.minecraft.fluid.Fluids;
import net.minecraft.fluid.IFluidState;
import net.minecraft.inventory.ItemStackHelper;
import net.minecraft.item.BlockItemUseContext;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.state.BooleanProperty;
import net.minecraft.state.DirectionProperty;
import net.minecraft.state.StateContainer.Builder;
import net.minecraft.state.properties.BlockStateProperties;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.ActionResultType;
import net.minecraft.util.Direction;
import net.minecraft.util.Hand;
import net.minecraft.util.Mirror;
import net.minecraft.util.NonNullList;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.Rotation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.BlockRayTraceResult;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.StringTextComponent;
import net.minecraft.util.text.TextFormatting;
import net.minecraft.util.text.TranslationTextComponent;
import net.minecraft.world.IBlockReader;
import net.minecraft.world.IWorld;
import net.minecraft.world.World;
import net.minecraft.world.storage.loot.LootContext;
import net.minecraft.world.storage.loot.LootParameters;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.fml.network.NetworkHooks;

public class GreedyChestBlock extends Block {

	public static final DirectionProperty FACING = HorizontalBlock.HORIZONTAL_FACING;
	public static final BooleanProperty WATERLOGGED = BlockStateProperties.WATERLOGGED;
	public static final ResourceLocation CONTENTS = new ResourceLocation("contents");

	public GreedyChestBlock(Properties properties) {
		super(properties);
		this.setDefaultState(this.stateContainer.getBaseState().with(FACING, Direction.NORTH).with(WATERLOGGED,
				Boolean.valueOf(false)));
	}

	public void neighborChanged(BlockState state, World worldIn, BlockPos pos, Block blockIn, BlockPos fromPos,
			boolean isMoving) {
		if (!worldIn.isRemote) {
			if (state.get(WATERLOGGED)) {
				worldIn.getPendingFluidTicks().scheduleTick(pos, Fluids.WATER, Fluids.WATER.getTickRate(worldIn));
			}
		}
	}

	public BlockState getStateForPlacement(BlockItemUseContext context) {
		BlockState blockstate = this.getDefaultState();
		IFluidState ifluidstate = context.getWorld().getFluidState(context.getPos());
		blockstate = blockstate.with(FACING, context.getPlacementHorizontalFacing().getOpposite());
		return blockstate.with(WATERLOGGED, Boolean.valueOf(ifluidstate.getFluid() == Fluids.WATER));
	}

	@Override
	protected void fillStateContainer(Builder<Block, BlockState> builder) {
		builder.add(FACING, WATERLOGGED);
	}

	@SuppressWarnings("deprecation")
	public IFluidState getFluidState(BlockState state) {
		return state.get(WATERLOGGED) ? Fluids.WATER.getStillFluidState(false) : super.getFluidState(state);
	}

	@SuppressWarnings("deprecation")
	public BlockState updatePostPlacement(BlockState stateIn, Direction facing, BlockState facingState, IWorld worldIn,
			BlockPos currentPos, BlockPos facingPos) {
		if (stateIn.get(WATERLOGGED)) {
			worldIn.getPendingFluidTicks().scheduleTick(currentPos, Fluids.WATER, Fluids.WATER.getTickRate(worldIn));
		}

		return super.updatePostPlacement(stateIn, facing, facingState, worldIn, currentPos, facingPos);
	}

	@Override
	public boolean hasTileEntity(BlockState stateIn) {
		return true;
	}

	@Override
	public TileEntity createTileEntity(BlockState stateIn, IBlockReader worldIn) {
		return ModTileEntityTypes.GREEDY_CHEST.get().create();
	}

	// 获取和设置方块自定义名称
	public void onBlockPlacedBy(World worldIn, BlockPos pos, BlockState state, LivingEntity placer, ItemStack stack) {
		if (stack.hasDisplayName()) {
			TileEntity tileentity = worldIn.getTileEntity(pos);
			if (tileentity instanceof GreedyChestTileEntity) {
				((GreedyChestTileEntity) tileentity).setCustomName(stack.getDisplayName());
			}
		}
	}

	@Override
	public ActionResultType onBlockActivated(BlockState state, World worldIn, BlockPos pos, PlayerEntity player,
			Hand handIn, BlockRayTraceResult hit) {
		if (worldIn.isRemote) {
			return ActionResultType.SUCCESS;
		} else if (player.isSpectator()) {
			return ActionResultType.SUCCESS;
		} else {
			TileEntity tile = worldIn.getTileEntity(pos);
			if (tile instanceof GreedyChestTileEntity) {
				NetworkHooks.openGui((ServerPlayerEntity) player, (GreedyChestTileEntity) tile, pos);
				return ActionResultType.SUCCESS;
			} else {
				return ActionResultType.PASS;
			}
		}
	}

	public static ItemStack getItemStack() {
		return new ItemStack(ModBlocks.GREEDY_CHEST.get());
	}

	public void onBlockHarvested(World worldIn, BlockPos pos, BlockState state, PlayerEntity player) {
		TileEntity tileentity = worldIn.getTileEntity(pos);
		if (tileentity instanceof GreedyChestTileEntity) {
			GreedyChestTileEntity greedyChestTileEntity = (GreedyChestTileEntity) tileentity;
			if (!worldIn.isRemote && player.isCreative() && !greedyChestTileEntity.isEmpty()) {
				ItemStack itemstack = getItemStack();
				CompoundNBT compoundnbt = greedyChestTileEntity.saveToNbt(new CompoundNBT());
				if (!compoundnbt.isEmpty()) {
					itemstack.setTagInfo("BlockEntityTag", compoundnbt);
				}

				if (greedyChestTileEntity.hasCustomName()) {
					itemstack.setDisplayName(greedyChestTileEntity.getCustomName());
				}

				ItemEntity itementity = new ItemEntity(worldIn, (double) pos.getX(), (double) pos.getY(),
						(double) pos.getZ(), itemstack);
				itementity.setDefaultPickupDelay();
				worldIn.addEntity(itementity);
			} else {
				greedyChestTileEntity.fillWithLoot(player);
			}
		}
		super.onBlockHarvested(worldIn, pos, state, player);
	}

	@SuppressWarnings("deprecation")
	public ItemStack getItem(IBlockReader worldIn, BlockPos pos, BlockState state) {
		ItemStack itemstack = super.getItem(worldIn, pos, state);
		GreedyChestTileEntity greedyChestTileEntity = (GreedyChestTileEntity) worldIn.getTileEntity(pos);
		CompoundNBT compoundnbt = greedyChestTileEntity.saveToNbt(new CompoundNBT());
		if (!compoundnbt.isEmpty()) {
			itemstack.setTagInfo("BlockEntityTag", compoundnbt);
		}
		return itemstack;
	}

	// 方块掉落
	@SuppressWarnings("deprecation")
	public List<ItemStack> getDrops(BlockState state, LootContext.Builder builder) {
		TileEntity tileentity = builder.get(LootParameters.BLOCK_ENTITY);
		if (tileentity instanceof GreedyChestTileEntity) {
			GreedyChestTileEntity greedyChestTileEntity = (GreedyChestTileEntity) tileentity;
			builder = builder.withDynamicDrop(CONTENTS, (p_220168_1_, p_220168_2_) -> {
				for (int i = 0; i < greedyChestTileEntity.getSizeInventory(); ++i) {
					p_220168_2_.accept(greedyChestTileEntity.getStackInSlot(i));
				}
			});
		}
		return super.getDrops(state, builder);
	}

	// 在标签页显示容器容纳的方块和数量
	@OnlyIn(Dist.CLIENT)
	public void addInformation(ItemStack stack, @Nullable IBlockReader worldIn, List<ITextComponent> tooltip,
			ITooltipFlag flagIn) {
		super.addInformation(stack, worldIn, tooltip, flagIn);
		CompoundNBT compoundnbt = stack.getChildTag("BlockEntityTag");
		if (compoundnbt != null) {
			if (compoundnbt.contains("LootTable", 8)) {
				tooltip.add(new StringTextComponent("???????"));
			}

			if (compoundnbt.contains("Items", 9)) {
				NonNullList<ItemStack> nonnulllist = NonNullList.withSize(GreedyChestContainer.inventorySize2,
						ItemStack.EMPTY);
				ItemStackHelper.loadAllItems(compoundnbt, nonnulllist);
				int i = 0;
				int j = 0;

				for (ItemStack itemstack : nonnulllist) {
					if (!itemstack.isEmpty()) {
						++j;
						if (i <= 4) {
							++i;
							ITextComponent itextcomponent = itemstack.getDisplayName().deepCopy();
							itextcomponent.applyTextStyle(TextFormatting.GRAY).appendText(" x")
									.appendText(String.valueOf(itemstack.getCount()));
							tooltip.add(itextcomponent);
						}
					}
				}

				if (j - i > 0) {
					tooltip.add((new TranslationTextComponent("container.shulkerBox.more", j - i))
							.applyTextStyle(TextFormatting.ITALIC).applyTextStyle(TextFormatting.BLUE));
				}
			}
		}

	}

	// 旋转和镜像支持
	public BlockState rotate(BlockState state, Rotation rot) {
		return state.with(FACING, rot.rotate(state.get(FACING)));
	}

	public BlockState mirror(BlockState state, Mirror mirrorIn) {
		return state.rotate(mirrorIn.toRotation(state.get(FACING)));
	}

	// 活塞推动支持
	public PushReaction getPushReaction(BlockState state) {
		return PushReaction.IGNORE;
	}

}
